package com.ptmall.app.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiCitySearchOption;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.facebook.stetho.common.LogUtil;

import java.io.Serializable;
import java.util.List;


/**
 * Created by zjh on 2017/5/2.
 * <p>
 * 对百度地图封装
 */

public class LocationUtil {
    private static MyLocationListenner myListener = new MyLocationListenner();//定位监听
    public static LocationClient mLocClient;
    public static GeoCoder geoCoder;//逆地理编码

    private static currentAddress mCurrentAddress;//定位回调监听
    private static poiSeach mPoi; //poi检索回调监听
    private static geoCode mGeoCode;//反地理编码查询
    private static mapMove mMapMove;//地图移动箭筒
    private static boolean isOnes = true;//是否之调用一次
    public static final int MAP_MOVE_START=1;
    public static final int MAP_MOVING=2;
    public static final int MAP_MOVE_END=3;
    public static final String MARK="mark";//mark保存数据的KEY


    public interface currentAddress {
        void getAddress(BDLocation location);
    }

    public interface poiSeach {
        void getPoi(List<PoiInfo> poiInfos);
    }

    public interface geoCode {
        void getGeoCode(ReverseGeoCodeResult reverseGeoCodeResult);
    }

    public interface mapMove {
        void getmapMove(MapStatus mapStatus, int state);
    }

    /**
     * 定位模块调用
     *
     * @param mCurrentAddress2
     */
    public static void setCurrentAddress(currentAddress mCurrentAddress2, Context mContext, boolean one) {
        mCurrentAddress = mCurrentAddress2;
        isOnes = one;
        getLocation(mContext);

    }

    /**
     * POI检索模块调用
     * 城市内检索
     * @param mPoiSeach
     * @param city
     * @param code
     */
    public static void setPoi(poiSeach mPoiSeach, String city, String code) {
        mPoi = mPoiSeach;
        poiSeach(city, code);
    }

    /**
     * 逆地理编码调用
     *
     * @param mGeo
     * @param mLatLng
     */
    public static void setGeoCode(geoCode mGeo, LatLng mLatLng) {
        mGeoCode = mGeo;
        geoCode(mLatLng);
    }

    /**
     * 地图移动监听调用
     * @param mMapmpve
     * @param mBaiduMap
     */
    public static void setMapMove(mapMove mMapmpve,BaiduMap mBaiduMap) {
        mMapMove=mMapmpve;
        mBaiduMap.setOnMapStatusChangeListener(onMapStatusChangeListener);
    }

    /**
     * 设置地图中心点调用
     * @param mBaiduMap  地图显示VIEW
     * @param latLng   地图经纬度
     */
    public static void setMapCenter(BaiduMap mBaiduMap, LatLng latLng){
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(latLng, 16);
        mBaiduMap.animateMapStatus(msu);
    }

    /**
     * 设置地图中心点调用
     * @param mBaiduMap   地图显示VIEW
     * @param latLng      地图中心点坐标
     * @param rank        地图缩放级别
     */
    public static void setMapCenter(BaiduMap mBaiduMap, LatLng latLng, int rank){
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLngZoom(latLng, rank);
        mBaiduMap.animateMapStatus(msu);
    }

    /**
     * 地图增加点调用
     * @param mBaiduMap   地图空间
     * @param mLatLng     经纬度
     * @param mBitmap     加点图标
     * @param info        点信息
     */
    public static void addMark(BaiduMap mBaiduMap, LatLng mLatLng, Bitmap mBitmap, Serializable info){
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromBitmap(mBitmap);
        Marker marker=null;
        OverlayOptions overlayoptions = new MarkerOptions()
                // 设置marker的位置
                .position(mLatLng)
                // 设置marker的图标
                .icon(bitmap)
                // 设置marker的所在层级
                .zIndex(9);
        marker=(Marker) mBaiduMap.addOverlay(overlayoptions);
        Bundle bundle=new Bundle();
        bundle.putSerializable(MARK, info);
        marker.setExtraInfo(bundle);
    }
    /**
     * 地图增加自定义样式点调用
     * @param mBaiduMap   地图空间
     * @param mLatLng     经纬度
     * @param view     自定义样式
     * @param info        点信息
     */
    public static void addMark(BaiduMap mBaiduMap, LatLng mLatLng, View view, Serializable info){
        Bitmap bitmap=getViewBitmap(view);
       addMark(mBaiduMap,mLatLng,bitmap,info);
    }

    /**
     * 地图弹框
     * @param mBaiduMap 地图控件
     * @param mLatLng   坐标
     * @param view      样式
     * @param Y        Y轴偏移量
     */
    public static void showMapPop(BaiduMap mBaiduMap, LatLng mLatLng, View view, int Y){
        InfoWindow infoWindow = new InfoWindow(view, mLatLng,Y);
        mBaiduMap.showInfoWindow(infoWindow);
    }







    /**
     * 定位模块
     */
    private static void getLocation(Context mContext) {
        // 定位初始化
        if (mLocClient == null) {
            mLocClient = new LocationClient(mContext);
            mLocClient.registerLocationListener(myListener);
            // 定位选项
            LocationClientOption option = new LocationClientOption();
            /**
             * coorType - 取值有3个： 返回国测局经纬度坐标系：gcj02 返回百度墨卡托坐标系 ：bd09 返回百度经纬度坐标系
             * ：bd09ll
             */
            option.setCoorType("bd09ll");
            // 设置是否需要地址信息，默认为无地址
            option.setIsNeedAddress(true);
            // 设置是否需要返回位置语义化信息，可以在BDLocation.getLocationDescribe()中得到数据，ex:"在天安门附近"，
            // 可以用作地址信息的补充
            option.setIsNeedLocationDescribe(true);
            // 设置是否需要返回位置POI信息，可以在BDLocation.getPoiList()中得到数据
            option.setIsNeedLocationPoiList(true);
            /**
             * 设置定位模式 Battery_Saving 低功耗模式 Device_Sensors 仅设备(Gps)模式 Hight_Accuracy
             * 高精度模式
             */
            option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
            // 设置是否打开gps进行定位
            option.setOpenGps(true);
            // 设置扫描间隔，单位是毫秒 当<1000(1s)时，定时定位无效
            option.setScanSpan(1000);

            // 设置 LocationClientOption
            mLocClient.setLocOption(option);
        }
        LogUtil.d("xucc","开始定位");
        mLocClient.start();
        mLocClient.requestLocation();

    }

    /**
     * 重写定位监听
     */
    private static class MyLocationListenner implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            // TODO Auto-generated method stub
            if (isOnes == true) {
                mLocClient.stop();
            }
            LogUtil.d("xucc","定位结束");
            mCurrentAddress.getAddress(location);
        }
    }

    /******************                定位模块结束                             ************************/

    /**
     * POI检索模块
     * @param city 检索城市
     * @param code 检索关键字
     */
    private static void poiSeach(String city, String code) {

        if(city==null){
            city="北京";
        }
        // 创建PoiSearch实例
        PoiSearch poiSearch = PoiSearch.newInstance();
        // 设置poi检索监听者
        poiSearch.setOnGetPoiSearchResultListener(new getPoiSearchResult());
        // 城市内检索
        PoiCitySearchOption poiCitySearchOption = new PoiCitySearchOption();
        // 关键字
        poiCitySearchOption.keyword(code);
        // 城市
        poiCitySearchOption.city(city);
        // 设置每页容量，默认为每页10条
        poiCitySearchOption.pageCapacity(100);
        // 分页编号
        poiCitySearchOption.pageNum(0);
        poiSearch.searchInCity(poiCitySearchOption);
    }
    private static class getPoiSearchResult implements OnGetPoiSearchResultListener {
        // poi 查询结果回调
        @Override
        public void onGetPoiResult(PoiResult poiResult) {
            try {
                mPoi.getPoi(poiResult.getAllPoi());
            } catch (Exception e) {
                mPoi.getPoi(null);
            }
        }
        // poi 详情查询结果回调
        @Override
        public void onGetPoiDetailResult(
                PoiDetailResult poiDetailResult) {
        }
        @Override
        public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
        }
    }
    /******************                POI检索模块结束                             ************************/

    /**
     * 逆地理编码解析
     *
     * @param latLng
     */
    private static void geoCode(LatLng latLng) {
        // 创建GeoCoder实例对象
        if (geoCoder == null) {
            geoCoder = GeoCoder.newInstance();
        }
        // 设置查询结果监听者
        geoCoder.setOnGetGeoCodeResultListener(new MyOnGetGeoCodeResultListener());
        // 发起反地理编码请求(经纬度->地址信息)
        ReverseGeoCodeOption reverseGeoCodeOption = new ReverseGeoCodeOption();
        // 设置反地理编码位置坐标
        reverseGeoCodeOption.location(latLng);

        geoCoder.reverseGeoCode(reverseGeoCodeOption);
    }

    private static class MyOnGetGeoCodeResultListener implements OnGetGeoCoderResultListener {
        @Override
        public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

        }

        @Override
        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
            try {
                mGeoCode.getGeoCode(reverseGeoCodeResult);
            } catch (Exception e) {
                Log.d("Exception", e.toString());
            }
        }
    }

    /**
     * 地图移动监听
     */

    public static BaiduMap.OnMapStatusChangeListener onMapStatusChangeListener= new BaiduMap.OnMapStatusChangeListener() {
        @Override
        public void onMapStatusChangeStart(MapStatus mapStatus) {
            mMapMove.getmapMove(mapStatus,MAP_MOVE_START);
        }

        @Override
        public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

        }

        @Override
        public void onMapStatusChange(MapStatus mapStatus) {
            mMapMove.getmapMove(mapStatus,MAP_MOVING);
        }

        @Override
        public void onMapStatusChangeFinish(MapStatus mapStatus) {
            mMapMove.getmapMove(mapStatus,MAP_MOVE_END);
        }
    };

    /**
     * 将View转换成Bitmap
     * @param addViewContent
     * @return
     */

    private static Bitmap getViewBitmap(View addViewContent) {
        addViewContent.setDrawingCacheEnabled(false);
        addViewContent.setDrawingCacheEnabled(true);
        addViewContent.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        addViewContent.layout(0, 0,
                addViewContent.getMeasuredWidth(),
                addViewContent.getMeasuredHeight());
        addViewContent.buildDrawingCache();
        return addViewContent.getDrawingCache();
    }
}